package modularity.passiveDrift;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class DiskStorage {

	private int threads;

	/**
	 * this method stores each genome in the population as a list of connections -- the result of to string.
	 * @throws IOException 
	 * @throws InterruptedException 
	 */
	public void store(ListedPopulation population, String currentOutputDirectory) throws IOException, InterruptedException {
		int populationsize = population.size();
		ExecutorService eservice = Executors.newFixedThreadPool(threads);
		CompletionService<Object> cservice = new ExecutorCompletionService<Object>(eservice);

		for(int i = 0; i < populationsize; i++){
			Genome<ConnectionGene> genome = population.get(i);

			cservice.submit(new StoringTask(genome, currentOutputDirectory + genome.getName() + ".txt"));
		}

		//call shutdown to prevent new tasks from being submitted
	    eservice.shutdown();
		
	    for(int index = 0; index < populationsize; index++) {
			Object result;
			try {
				result = cservice.take().get();
			} catch (InterruptedException e) {
	            // Something went wrong with a task submitted
	            System.out.println("Error Interrupted exception");
	            e.printStackTrace();
	        } catch (ExecutionException e) {
	            // Something went wrong with the result
	            e.printStackTrace();
	            System.out.println("Error get() threw exception");
	        }
		}
	}

	public void setNumberOfThreads(int evaluationThreads) {
		this.threads = evaluationThreads;
	}

	private class StoringTask implements Callable<Object>{

		private Genome<ConnectionGene> genome;
		private String outputFile;

		StoringTask(Genome<ConnectionGene> genome, String file) {
			this.genome = genome;
			this.outputFile = file;
		}

		@Override
		public Object call() throws Exception {
			BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile));
			writer.write(genome.toString());
			writer.close();
			
			return null;
		}
	}

}
